#if _MSC_VER
 #pragma once
#endif // _MSC_VER

#ifndef __HERZELEID_SWAPSETARRAY_INCLUDED__
 #define __HERZELEID_SWAPSETARRAY_INCLUDED__
 #define MoveByRef std::move
 #include "HerzeleidRendererShading.hxx"

 #ifdef HERZELEID_DESKTOP
  #include "HerzeleidArray.hxx"

HerzeleidRendererShadingNamespaceBegin template <class TSet> 
class SwapSetArray : public Platform::Array<TSet>
{
public:
	typedef Platform::Array<TSet> SetArray;

public:
	SwapSetArray() : 
		SetArray()
	{
	}

	SwapSetArray( _In_ UInt32 NumElements, _In_opt_ HResult *Result = nullptr ) : 
		SetArray( NumElements, Result )
	{
	}

	~SwapSetArray()
	{
		SetArray::Deallocate();
	}

	HERZELEID_FORCEINLINING Void UnsafeSwap( 
		_In_opt_ _In_range_(0, Size-1) UInt32 uiPos0 = 0u, 
		_In_opt_ _In_range_(0, Size-1) UInt32 uiPos1 = 1u
		)
	{
		MoveByRef(
			SetArray::m_Elements[uiPos0], 
			SetArray::m_Elements[uiPos1]
			);
	}

	HERZELEID_HINTINLINING HResult Swap(
		_In_opt_ _In_range_(0, Size-1) UInt32 uiPos0 = 0u, 
		_In_opt_ _In_range_(0, Size-1) UInt32 uiPos1 = 1u
		)
	{
		if (uiPos0 == uiPos1) return( S_OK );
		else if ((uiPos0 >= SetArray::m_NumElements) || (uiPos1 >= SetArray::m_NumElements)) return( E_BOUNDS );
		UnsafeSwap( uiPos0, uiPos1 ); 
		return( S_OK );
	}

} HerzeleidRendererShadingNamespaceEnd;

 #else
HerzeleidRendererShadingNamespaceBegin template <class TSet> ref class SwapSetArray
{
private:

	Platform::Array<TSet>^ m_Elements;

public:

	SwapSetArray( )
	{
	}

	SwapSetArray( UInt32 uNumElements )
	{
		Length = uNumElements;
	}

	property UInt32 Length 
	{
		UInt32 get()
		{
			return m_Elements->Length;
		}

		void set( UInt32 uValue )
		{
			m_Elements = ref new Platform::Array<TSet>(uValue);
		}
	}

	property TSet *Data
	{
		TSet *get()
		{
			return m_Elements->Data;
		}
	}

	HERZELEID_FORCEINLINING Void UnsafeSwap( 
		_In_opt_ _In_range_(0, Size-1) UInt32 uiPos0 = 0u, 
		_In_opt_ _In_range_(0, Size-1) UInt32 uiPos1 = 1u
		)
	{
		MoveByRef(
			m_Elements->Data[uiPos0], 
			m_Elements->Data[uiPos1]
			);
	}

	HERZELEID_HINTINLINING HResult Swap(
		_In_opt_ _In_range_(0, Size-1) UInt32 uiPos0 = 0u, 
		_In_opt_ _In_range_(0, Size-1) UInt32 uiPos1 = 1u
		)
	{
		if (uiPos0 == uiPos1) return( S_OK );
		else if ((uiPos0 >= m_Elements->Length) || (uiPos1 >= m_Elements->Length)) return( E_BOUNDS );
		UnsafeSwap( uiPos0, uiPos1 ); 
		return( S_OK );
	}

} HerzeleidRendererShadingNamespaceEnd
#endif

#endif // !__HERZELEID_SWAPSETARRAY_INCLUDED__